package android.slc.box.core.virtual_android;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.annotations.Nullable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;

public class Bundle extends LinkedHashMap<String, Serializable> {

    public <T> T get(String key, Serializable defValue) {
        Serializable value = get(key);
        if (value == null) {
            return (T) defValue;
        } else {
            return (T) value;
        }
    }

    public void putBoolean(@Nullable String key, boolean value) {
        put(key, value);
    }

    public void putByte(@Nullable String key, byte value) {
        put(key, value);
    }

    public void putChar(@Nullable String key, char value) {
        put(key, value);
    }

    public void putShort(@Nullable String key, short value) {
        put(key, value);
    }

    public void putInt(@Nullable String key, int value) {
        put(key, value);
    }

    public void putLong(@Nullable String key, long value) {
        put(key, value);
    }

    public void putFloat(@Nullable String key, float value) {
        put(key, value);
    }

    public void putDouble(@Nullable String key, double value) {
        put(key, value);
    }

    public void putString(@Nullable String key, @Nullable String value) {
        put(key, value);
    }

    public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
        put(key, value);
    }

    public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
        put(key, value);
    }

    public void putSerializable(@Nullable String key, @Nullable Serializable value) {
        put(key, value);
    }

    public void putBooleanArray(@Nullable String key, @Nullable boolean[] value) {
        put(key, value);
    }

    public void putByteArray(@Nullable String key, @Nullable byte[] value) {
        put(key, value);
    }

    public void putShortArray(@Nullable String key, @Nullable short[] value) {
        put(key, value);
    }

    public void putCharArray(@Nullable String key, @Nullable char[] value) {
        put(key, value);
    }

    public void putIntArray(@Nullable String key, @Nullable int[] value) {
        put(key, value);
    }

    public void putLongArray(@Nullable String key, @Nullable long[] value) {
        put(key, value);
    }

    public void putFloatArray(@Nullable String key, @Nullable float[] value) {
        put(key, value);
    }

    public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
        put(key, value);
    }

    public void putBundle(@Nullable String key, @Nullable Bundle value) {
        put(key, value);
    }

    public byte getByte(String key) {
        return (byte) get(key);
    }

    public Byte getByte(String key, byte defaultValue) {
        return get(key, defaultValue);
    }

    public char getChar(String key) {
        return (char) get(key);
    }

    public char getChar(String key, char defaultValue) {
        return get(key, defaultValue);
    }

    public short getShort(String key) {
        return (short) get(key);
    }

    public short getShort(String key, short defaultValue) {
        return get(key, defaultValue);
    }

    public int getInt(String key) {
        return getInt(key, 0);
    }

    public int getInt(String key, int defaultValue) {
        Object o = get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Integer) o;
        } catch (ClassCastException e) {
            return defaultValue;
        }
    }

    public long getLong(String key) {
        return getLong(key, 0L);
    }

    public long getLong(String key, long defaultValue) {
        Object o = get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Long) o;
        } catch (ClassCastException e) {
            return defaultValue;
        }
    }

    public float getFloat(String key) {
        return (float) get(key);
    }

    public float getFloat(String key, float defaultValue) {
        return get(key, defaultValue);
    }

    public double getDouble(String key) {
        return getDouble(key, 0.0);
    }

    public double getDouble(String key, double defaultValue) {
        Object o = get(key);
        if (o == null) {
            return defaultValue;
        }
        try {
            return (Double) o;
        } catch (ClassCastException e) {
            return defaultValue;
        }
    }

    @Nullable
    public String getString(@Nullable String key) {
        final Object o = get(key);
        try {
            return (String) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    public String getString(@Nullable String key, String defaultValue) {
        final String s = getString(key);
        return (s == null) ? defaultValue : s;
    }

    public Bundle getBundle(@Nullable String key) {
        return (Bundle) get(key);
    }

    public Serializable getSerializable(@Nullable String key) {
        return get(key);
    }

    @Nullable
    <T extends Serializable> T getSerializable(@Nullable String key, @NonNull Class<T> clazz) {
        return get(key, clazz);
    }

    @Nullable
    <T> ArrayList<T> getArrayList(@Nullable String key) {
        try {
            return (ArrayList<T>) get(key);
        } catch (ClassCastException e) {
            return null;
        }
    }

    @Nullable
    public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
        return (ArrayList<Integer>) get(key);
    }

    @Nullable
    public ArrayList<String> getStringArrayList(@Nullable String key) {
        return (ArrayList<String>) get(key);
    }

    @Nullable
    public byte[] getByteArray(@Nullable String key) {
        Object o = get(key);
        if (o == null) {
            return null;
        }
        try {
            return (byte[]) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    @Nullable
    public short[] getShortArray(@Nullable String key) {
        Object o = get(key);
        if (o == null) {
            return null;
        }
        try {
            return (short[]) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    @Nullable
    public char[] getCharArray(@Nullable String key) {
        Object o = get(key);
        if (o == null) {
            return null;
        }
        try {
            return (char[]) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    @Nullable
    public int[] getIntArray(@Nullable String key) {
        Object o = get(key);
        if (o == null) {
            return null;
        }
        try {
            return (int[]) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    @Nullable
    public long[] getLongArray(@Nullable String key) {
        Object o = get(key);
        if (o == null) {
            return null;
        }
        try {
            return (long[]) o;
        } catch (ClassCastException e) {
            return null;
        }
    }

    public float[] getFloatArray(@Nullable String key) {
        return (float[]) get(key);
    }

}
